package com.yss.reportworld.service.impl;

import java.sql.Connection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yss.common.core.constant.RequestDataHelper;
import com.yss.common.core.exception.BusinessException;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.core.utils.uuid.IdUtils;
import com.yss.common.security.utils.SecurityUtils;
import com.yss.reportworld.domain.*;
import com.yss.reportworld.enums.ReportWorldEnum;
import com.yss.reportworld.mapper.DataCustomerMapper;
import com.yss.reportworld.mapper.DataModularMapper;
import com.yss.reportworld.mapper.DataReportMapper;
import com.yss.reportworld.service.*;
import com.yss.reportworld.util.TableInfoUtil;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.stereotype.Service;
import com.yss.reportworld.mapper.DatasqlMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;

/**
 * 函数信息Service业务层处理
 *
 * @author yss
 * @date 2023-03-27
 */
@Slf4j
@Service
public class DatasqlServiceImpl extends ServiceImpl<DatasqlMapper, Datasql> implements IDatasqlService {
    @Autowired
    private DatasqlMapper datasqlMapper;
    @Autowired
    private IDatabaseCheckService databaseCheckService;
    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;
    @Autowired
    private DataReportMapper dataReportMapper;
    @Autowired
    private DataModularMapper dataModularMapper;
    @Autowired
    private DataCustomerMapper dataCustomerMapper;

    /**
     * 查询函数信息列表
     *
     * @param datasql 函数信息
     * @return 函数信息
     */
    @Override
    public List<Datasql> selectDatasqlList(Datasql datasql) {
        try {
            TableInfoUtil.handleTableVersion(datasql.getHisVersion()); // 替换表名
            QueryWrapper<Datasql> wrapper = new QueryWrapper();
            if (null == datasql) {
                return this.list(wrapper);
            }
            if (StringUtils.isNotEmpty(datasql.getName())) {
                wrapper.like("a.NAME", datasql.getName());
            }
            if (StringUtils.isNotEmpty(datasql.getChineseName())) {
                wrapper.like("a.CHINESE_NAME", datasql.getChineseName());
            }
            if (StringUtils.isNotEmpty(datasql.getVersion())) {
                wrapper.like("a.VERSION", datasql.getVersion());
            }
            if (StringUtils.isNotEmpty(datasql.getDataBaseType())) {
                wrapper.like("a.DATABASE_TYPE", datasql.getDataBaseType());
            }
            if (null != datasql.getOrderType()) {
                wrapper.like("a.ORDER_TYPE", datasql.getOrderType());
            }
            if (null != datasql.getType()) {
                wrapper.eq("a.TYPE", datasql.getType());
            }
            if (null != datasql.getStatus()) {
                wrapper.eq("a.STATUS", datasql.getStatus());
            }
            if (StringUtils.isNotEmpty(datasql.getStrReport())) {
                wrapper.in("b.REPORT_ID", datasql.getStrReport());
            }
            if (StringUtils.isNotEmpty(datasql.getStrModular())) {
                wrapper.in("c.MODULAR_ID", datasql.getStrModular());
            }
            if (StringUtils.isNotEmpty(datasql.getStrCustomer())) {
                wrapper.in("d.CUSTOMER_ID", datasql.getStrCustomer());
            }
            // 导出的时候选择了数据，按照选择的数据
            if (StringUtils.isNotEmpty(datasql.getIds())) {
                List<String> list = JSONArray.parseArray(datasql.getIds(), String.class);
                if (StringUtils.isNotEmpty(list)) {
                    wrapper.in("a.ID", list);
                }
            }
            List<Datasql> list = datasqlMapper.queryDatasql(wrapper);
            if (StringUtils.isEmpty(list)) {
                return list;
            }
            for (Datasql datasqlInfo : list) {
                this.setDatasqlInfo(datasqlInfo);
            }
            return list;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    private void setDatasqlInfo(Datasql datasqlInfo) {
        // 所属模块
        DataModular modular = new DataModular();
        modular.setDataId(datasqlInfo.getId());
        modular.setDataCode(ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
        List<DataModular> listModular = dataModularMapper.selectPrimaryByDataId(modular);
        if (StringUtils.isNotEmpty(listModular)) {
            StringBuffer modularName = new StringBuffer();
            for (DataModular dataModular : listModular) {
                modularName.append(dataModular.getModularName()).append("/");
            }
            datasqlInfo.setStrModularName(modularName.deleteCharAt(modularName.length() - 1).toString());
            datasqlInfo.setStrModular(listModular.stream().map(DataModular::getModularId).collect(Collectors.toList()));
        }
        // 所属客户
        DataCustomer customer = new DataCustomer();
        customer.setDataId(datasqlInfo.getId());
        customer.setDataCode(ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
        List<DataCustomer> listCustomer = dataCustomerMapper.selectPrimaryByDataId(customer);
        if (StringUtils.isNotEmpty(listCustomer)) {
            StringBuffer customerName = new StringBuffer();
            for (DataCustomer dataCustomer : listCustomer) {
                customerName.append(dataCustomer.getCustomerName()).append("/");
            }
            datasqlInfo.setStrCustomerName(customerName.deleteCharAt(customerName.length() - 1).toString());
            datasqlInfo.setStrCustomer(listCustomer.stream().map(DataCustomer::getCustomerId).collect(Collectors.toList()));
        }
        // 所属报表
        DataReport report = new DataReport();
        report.setDataId(datasqlInfo.getId());
        report.setDataCode(ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
        List<DataReport> listReport = dataReportMapper.selectPrimaryByDataId(report);
        if (StringUtils.isNotEmpty(listReport)) {
            StringBuffer reportName = new StringBuffer();
            for (DataReport dataReport : listReport) {
                reportName.append(dataReport.getReportName()).append("/");
            }
            datasqlInfo.setStrReportName(reportName.deleteCharAt(reportName.length() - 1).toString());
            datasqlInfo.setStrReport(listReport.stream().map(DataReport::getReportId).collect(Collectors.toList()));
        }
    }

    /**
     * 获取 脚本详细信息  ，包含字段所属客户，模块。客户
     *
     * @param datasql
     * @return
     */
    public Datasql selectDatasqlById(Datasql datasql) {
        try {
            TableInfoUtil.handleTableVersion(datasql.getHisVersion()); // 替换表名
            QueryWrapper<Datasql> wrapper = new QueryWrapper<>();
            wrapper.eq("a.ID", datasql.getId());
            List<Datasql> list = datasqlMapper.queryDatasql(wrapper);
            if (StringUtils.isEmpty(list) || StringUtils.isNull(list.get(0))) {
                return null;
            }
            Datasql datasqlOne = list.get(0);
            this.setDatasqlInfo(datasqlOne);
            return datasqlOne;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 校验名称是否唯一
     * 现在不校验唯一
     *
     * @param datasql
     * @return 结果
     */
    @Override
    public boolean checkDatasqlNameUnique(Datasql datasql) {
        try {
            TableInfoUtil.handleTableVersion(datasql.getHisVersion()); // 替换表名
            String datasqlId = StringUtils.isNull(datasql.getId()) ? "-1" : datasql.getId();
            QueryWrapper<Datasql> wrapper = new QueryWrapper<>();
            wrapper.eq("NAME", datasql.getName());
            wrapper.eq("DATABASE_TYPE", datasql.getDataBaseType());
            Datasql info = this.getOne(wrapper);
            if (StringUtils.isNotNull(info) && !info.getId().equals(datasqlId)) {
                return false;
            }
            return true;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 添加表信息
     *
     * @param datasql
     * @return
     */
    @Override
    @Transactional
    public void addDatasql(Datasql datasql) {
        try {
            TableInfoUtil.handleTableVersion(datasql.getHisVersion()); // 替换表名
            datasql.setId(IdUtils.fastSimpleUUID());
            datasql.setCreateBy(SecurityUtils.getUsername());
            datasql.setCreateTime(new Date());
            datasql.setName(datasql.getName().toUpperCase());
            this.addDatasqlInfo(datasql);
            this.save(datasql);
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            String msgInfo = databaseCheckService.checkDataBaseAllByCode(ReportWorldEnum.REPORT_DATASQL_CODE.getDesc(), connection, "");
            if (StringUtils.isNotEmpty(msgInfo)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BusinessException(msgInfo);
            }
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 修改表信息
     *
     * @param datasql
     * @return
     */
    @Override
    @Transactional
    public void editDatasql(Datasql datasql) {
        try {
            TableInfoUtil.handleTableVersion(datasql.getHisVersion()); // 替换表名
            datasql.setUpdateTime(new Date());
            datasql.setName(datasql.getName().toUpperCase());
            datasql.setUpdateBy(SecurityUtils.getUsername());
            //删除表和客户信息关联关系
            QueryWrapper<DataCustomer> wrapperCustomer = new QueryWrapper<>();
            wrapperCustomer.in("DATA_ID", datasql.getId());
            wrapperCustomer.eq("DATA_CODE", ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            dataCustomerMapper.delete(wrapperCustomer);
            //删除表和模块信息关联关系
            QueryWrapper<DataModular> wrapperModular = new QueryWrapper<>();
            wrapperModular.in("DATA_ID", datasql.getId());
            wrapperModular.eq("DATA_CODE", ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            dataModularMapper.delete(wrapperModular);
            //删除表和报表信息关联关系
            QueryWrapper<DataReport> wrapperReport = new QueryWrapper<>();
            wrapperReport.in("DATA_ID", datasql.getId());
            wrapperReport.eq("DATA_CODE", ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            dataReportMapper.delete(wrapperReport);
            this.addDatasqlInfo(datasql);
            this.updateById(datasql);
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            String msgInfo = databaseCheckService.checkDataBaseAllByCode(ReportWorldEnum.REPORT_DATASQL_CODE.getDesc(), connection, "");
            if (StringUtils.isNotEmpty(msgInfo)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BusinessException(msgInfo);
            }
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }


    /**
     * 保存脚本的关联关系信息
     */
    private void addDatasqlInfo(Datasql datasql) {
        if (StringUtils.isNotEmpty(datasql.getStrCustomer())) {
            for (String str : datasql.getStrCustomer()) {
                DataCustomer dataCustomer = new DataCustomer();
                dataCustomer.setId(IdUtils.fastSimpleUUID());
                dataCustomer.setCustomerId(str);
                dataCustomer.setDataId(datasql.getId());
                dataCustomer.setDataCode(ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
                dataCustomerMapper.insert(dataCustomer);
            }
        }
        if (StringUtils.isNotEmpty(datasql.getStrModular())) {
            for (String str : datasql.getStrModular()) {
                DataModular dataModular = new DataModular();
                dataModular.setId(IdUtils.fastSimpleUUID());
                dataModular.setModularId(str);
                dataModular.setDataId(datasql.getId());
                dataModular.setDataCode(ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
                dataModularMapper.insert(dataModular);
            }
        }
        if (StringUtils.isNotEmpty(datasql.getStrReport())) {
            for (String str : datasql.getStrReport()) {
                DataReport dataReport = new DataReport();
                dataReport.setId(IdUtils.fastSimpleUUID());
                dataReport.setReportId(str);
                dataReport.setDataId(datasql.getId());
                dataReport.setDataCode(ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
                dataReportMapper.insert(dataReport);
            }
        }
    }


    /**
     * 删除脚本信息
     *
     * @param datasql
     */
    @Transactional
    public void deleteDatasql(Datasql datasql) {
        try {
            TableInfoUtil.handleTableVersion(datasql.getHisVersion()); // 替换表名
            //删除表和客户信息关联关系
            QueryWrapper<DataCustomer> wrapperCustomer = new QueryWrapper<>();
            wrapperCustomer.in("DATA_ID", datasql.getIdList());
            wrapperCustomer.eq("DATA_CODE", ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            dataCustomerMapper.delete(wrapperCustomer);
            //删除表和模块信息关联关系
            QueryWrapper<DataModular> wrapperModular = new QueryWrapper<>();
            wrapperModular.in("DATA_ID", datasql.getIdList());
            wrapperModular.eq("DATA_CODE", ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            dataModularMapper.delete(wrapperModular);
            //删除表和报表信息关联关系
            QueryWrapper<DataReport> wrapperReport = new QueryWrapper<>();
            wrapperReport.in("DATA_ID", datasql.getIdList());
            wrapperReport.eq("DATA_CODE", ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            dataReportMapper.delete(wrapperReport);
            this.removeByIds(datasql.getIdList());
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }
}
